﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Scripting.AST.ObjectModel;
using IWMAG.Scripting.Types;
using IWMAG.Scripting.AST.TerminalExpressions;
using IWMAG.Scripting.Interpreter;
using IWMAG.Scripting.Compiler.UserInfo;

namespace IWMAG.Scripting.AST.Statements {
    internal class BreakStatement : CodeStatement {
        public CodeExpression Value;

        public BreakStatement(Compiler.Lexeme l, CodeExpression val = null)
            : base(l) {
            Value = val != null ? val : new IntExpression(l, 1);
        }

        public override void Verify(Helpers.CompileTable sym, List<Compiler.IUserInfo> error) {
            Value.Verify(sym, error);
            if (Value.TypeOf() != CodeType.Int) {
                SendError(error, Rules.BreakStatementArgumentMustBeInteger);
            }
        }

        public override IEnumerable<Continuation> Execute(Interpreter.ScriptEngine engine, Helpers.RuntimeTable sym) {
            Reference<RunValue> val = RunValue.NoValue;
            foreach (Continuation wait in Value.ValueOf(engine, sym, val)) yield return wait;
            if (val.ReferencedValue.IntValue >= 1 && val.ReferencedValue.IntValue <= 999) {
                yield return new Continuation(Continuation.Token.Break, val.ReferencedValue.IntValue);
            }
            yield break;
        }
    }
}
